const MongoClient = require("mongodb").MongoClient;

//find => 查询
const find = function (mongo, whereParams) {
  return new Promise((resolve, reject) => {
    MongoClient.connect(mongo.url, { useNewUrlParser: true }, async function (err, db) {
      //if (err) throw err;
      if (err) reject([err, mongo, whereParams]);
      var dbo = db.db(mongo.db);
      return await dbo
        .collection(mongo.collection)
        .find(whereParams)
        .toArray(function (err, result) {
          //if (err) throw err;
          //console.log(result);
          db.close();
          if (err) reject([err, mongo, whereParams]);
          else{
            resolve(result);
          }
        });
    });
  });
};

//count => 查询行数
const count = function (mongo, whereParams) {
  return new Promise((resolve, reject) => {
    MongoClient.connect(mongo.url, { useNewUrlParser: true }, async function (err, db) {
      //if (err) throw err;
      if (err) reject([err, mongo, whereParams]);
      var dbo = db.db(mongo.db);
      return await dbo
        .collection(mongo.collection)
        .find(whereParams)
        .count(function (err, result) {
          //if (err) throw err;
          //console.log(result);
          db.close();
          if (err) reject([err, mongo, whereParams]);
          else{
            resolve(result);
          }
        });
    });
  });
};

//单条insert
const insertOne = function (mongo, object) {
  return new Promise((resolve, reject) => {
    MongoClient.connect(mongo.url, { useNewUrlParser: true }, function (err,db) {
      if (err) reject([err, mongo, object]);
      var dbo = db.db(mongo.db);
      dbo.collection(mongo.collection).insertOne(object, function (err, res) {
        db.close();
        if (err) reject([err, mongo, object]);
        else{
          resolve(res);
        }
      });
    });
  });
};


//批量insert
const insertMany = function (mongo, array) {
  return new Promise((resolve, reject) => {
    MongoClient.connect(mongo.url, { useNewUrlParser: true }, function (err, db) {
      if (err) reject([err, mongo, array]);
      var dbo = db.db(mongo.db);
      dbo.collection(mongo.collection).insertMany(array, function (err, res) {
        db.close();
        if (err) reject([err, mongo, array]);
        if (!res || !res.insertedCount) {reject([err, mongo,array]);}
        else{
          resolve(`${mongo.collection}集合` + "插入的文档数量为: " + res.insertedCount);
        }
      });
    });
  });
};

/*
// 修改器名称：$set
// 语法：
{$set:{field: value}}
// example:
{$set:{name:"Redis"}}
//可以更新
*/
//批量更新 => 多条记录更新成同一值
//whereParams 查询条件
const updateMany = function (mongo, whereParams, object) {
  return new Promise((resolve, reject) => {
    MongoClient.connect(mongo.url, { useNewUrlParser: true }, function (err, db) {
      if (err) reject([err, mongo, whereParams, object]);
      var dbo = db.db(mongo.db);
      var updateStr = { $set: object };
      dbo.collection(mongo.collection).updateMany(whereParams, updateStr, function (err, res) {
        db.close();
        if (err) reject(err);
        if (!res || !res.result) {reject([err, mongo, whereParams,object]);}
        else{
          resolve(`${mongo.collection}集合的` + res.result.nModified + " 条文档被更新");
        }
      });
    });
  });
};

const deleteMany = function (mongo, whereParams, object) {
  return new Promise((resolve, reject) => {
    MongoClient.connect(mongo.url, { useNewUrlParser: true }, function (err, db) {
      if (err) reject([err, mongo, whereParams]);
      var dbo = db.db(mongo.db);
      var whereStr = { type: "en" };  // 查询条件
      dbo.collection(mongo.collection).deleteMany(whereParams, function (err, obj) {
        if (err) reject([err, mongo, whereParams]);
        else
        {
          resolve(`${mongo.collection}集合的` + obj.result.n + " 条文档被删除");
        }
      });
    });
  });
};

//find => 查询
const findPaged = function (mongo, whereParams,skip,limit) {
  return new Promise((resolve, reject) => {
    MongoClient.connect(mongo.url, { useNewUrlParser: true }, async function (err, db) {
      //if (err) throw err;
      if (err) reject([err, mongo, whereParams]);
      var dbo = db.db(mongo.db);
      return await dbo
        .collection(mongo.collection)
        .find(whereParams).skip(skip).limit(limit)
        .toArray(function (err, result) {
          //if (err) throw err;
          //console.log(result);
          db.close();
          if (err) reject([err, mongo, whereParams]);
          else{
            resolve(result);
          }
        });
    });
  });
};

//聚合返回某字段最大值
const groupMax = function (mongo,whereParams,key) {
  return new Promise((resolve, reject) => {
    MongoClient.connect(mongo.url, { useNewUrlParser: true }, async function (err, db) {
      //if (err) throw err;
      if (err) reject([err, mongo, whereParams]);
      let dbo = db.db(mongo.db);
      let aggregate = [
        {
          $match:whereParams
        },
        {
          $group:{
            _id:1
          },
          //key:{$MAX:key}
        }
      ];
      aggregate[1]['$group'][key] = {'$max':`$${key}`};
      return await dbo
        .collection(mongo.collection).aggregate(aggregate).toArray(function (err, result) {
          //if (err) throw err;
          //console.log(result);
          db.close();
          if (err) reject([err, mongo, whereParams]);
          else{
            resolve(result);
          }
        });
    });
  });
};


module.exports.updateMany = updateMany;
module.exports.insertMany = insertMany;
module.exports.insertOne = insertOne;
module.exports.deleteMany = deleteMany;
module.exports.find = find;
module.exports.count = count;
module.exports.findPaged = findPaged;
module.exports.groupMax = groupMax;

